﻿namespace ImageProcessing
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Windows.Forms.DataVisualization.Charting;

    /// <summary>
    /// To put a Histogram in a form
    /// </summary>
    public class HistogramInForms
    {
        /// <summary>
        /// Object of class Histogram
        /// </summary>
        private Histogram histo = new Histogram();

        /// <summary>
        /// Checks if its busy.
        /// </summary>
        private bool busy = false;

        /// <summary>
        /// Reference to the image
        /// </summary>
        private DImage image;

        /// <summary>
        /// Histogram Chart
        /// </summary>
        private Chart chartHistogram;

        /// <summary>
        /// Red Checkbox 
        /// </summary>
        private CheckBox chkRed;

        /// <summary>
        /// Green Checkbox 
        /// </summary>
        private CheckBox chkGreen;

        /// <summary>
        /// Blue Checkbox 
        /// </summary>
        private CheckBox chkBlue;

        /// <summary>
        /// Red Checkbox 
        /// </summary>
        private CheckBox chkGray;

        /// <summary>
        /// Initializes a new instance of the <see cref="HistogramInForms"/> class.
        /// </summary>
        /// <param name="i">The i.</param>
        /// <param name="histoChart">The histo chart.</param>
        /// <param name="red">The red.</param>
        /// <param name="green">The green.</param>
        /// <param name="blue">The blue.</param>
        /// <param name="gray">The gray.</param>
        public HistogramInForms(DImage i, Chart histoChart, CheckBox red, CheckBox green, CheckBox blue, CheckBox gray)
        {
            if (i == null)
            {
                return;
            }

            this.image = i;
            this.chkRed = red;
            this.chkGreen = green;
            this.chkBlue = blue;
            this.chkGray = gray;
            if (red != null)
            {
                this.chkRed.Checked = true;
                this.chkGreen.Checked = true;
                this.chkBlue.Checked = true;
                this.chkGray.Checked = true;
            }

            this.chartHistogram = histoChart;
            this.SetSeries();
            this.GetColorArrays();
            this.AddAllPoints();
        }

        /// <summary>
        /// Gets the color arrays.
        /// </summary>
        public void GetColorArrays()
        {
            this.histo.UpdateHistogram(this.image);
        }

        /// <summary>
        /// Adds the red points to the Chart.
        /// </summary>
        public void AddRedPoints()
        {
            for (int i = 0; i < 256; i++)
            {
                this.chartHistogram.Series["Red"].Points.Add(new DataPoint(i, this.histo.Red1[i]));
            }
        }

        /// <summary>
        /// Adds the green points to the Chart.
        /// </summary>
        public void AddGreenPoints()
        {
            for (int i = 0; i < 256; i++)
            {
                this.chartHistogram.Series["Green"].Points.Add(new DataPoint(i, this.histo.Green1[i]));
            }
        }

        /// <summary>
        /// Adds the blue points to the Chart.
        /// </summary>
        public void AddBluePoints()
        {
            for (int i = 0; i < 256; i++)
            {
                this.chartHistogram.Series["Blue"].Points.Add(new DataPoint(i, this.histo.Blue1[i]));
            }
        }

        /// <summary>
        /// Adds the gray points to the Chart.
        /// </summary>
        public void AddGrayPoints()
        {
            for (int i = 0; i < 256; i++)
            {
                this.chartHistogram.Series["Gray"].Points.Add(new DataPoint(i, this.histo.Gray1[i]));
            }
        }

        /// <summary>
        /// Adds all points.
        /// </summary>
        public void AddAllPoints()
        {
            this.AddRedPoints();
            this.AddGreenPoints();
            this.AddBluePoints();
            this.AddGrayPoints();
        }

        /// <summary>
        /// Updates all points.
        /// </summary>
        /// <param name="i">The i.</param>
        public void UpdateAllPoints(DImage i)
        {
            this.image = i;
            this.GetColorArrays();
            this.chartHistogram.Series["Red"].Points.Clear();
            this.chartHistogram.Series["Green"].Points.Clear();
            this.chartHistogram.Series["Blue"].Points.Clear();
            this.chartHistogram.Series["Gray"].Points.Clear();
            this.AddRedPoints();
            this.AddGreenPoints();
            this.AddBluePoints();
            this.AddGrayPoints();
        }

        /// <summary>
        /// Updates all points.
        /// </summary>
        /// <param name="imgStruct">The img struct.</param>
        public void UpdateAllPoints(ImageStructure[,] imgStruct)
        {
            this.image.ImageStructArray = imgStruct;
            this.GetColorArrays();
            this.chartHistogram.Series["Red"].Points.Clear();
            this.chartHistogram.Series["Green"].Points.Clear();
            this.chartHistogram.Series["Blue"].Points.Clear();
            this.chartHistogram.Series["Gray"].Points.Clear();
            this.AddRedPoints();
            this.AddGreenPoints();
            this.AddBluePoints();
            this.AddGrayPoints();
        }

        /// <summary>
        /// Handles the CheckedChanged event of the Chk control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        /// <param name="shift">if set to <c>true</c> [shift].</param>
        private void Chk_CheckedChanged(object sender, EventArgs e, bool shift)
        {
            if (this.busy)
            {
                return;
            }

            this.busy = true;

            CheckBox chk = (CheckBox)sender;
            if (shift)
            {
                this.DisableAllSeries();
                chk.Checked = true;
                this.chartHistogram.Series[chk.Name.Substring(4)].Enabled = true;
            }
            else if (Control.ModifierKeys == Keys.ControlKey)
            {
                this.EnableAllSeries();
                chk.Checked = false;
                this.chartHistogram.Series[chk.Name.Substring(4)].Enabled = false;
            }
            else
            {
                if (chk.Checked)
                {
                    this.chartHistogram.Series[chk.Name.Substring(4)].Enabled = true;
                }
                else
                {
                    this.chartHistogram.Series[chk.Name.Substring(4)].Enabled = false;
                }
            }

            this.busy = false;
        }

        /// <summary>
        /// Disables all series.
        /// </summary>
        private void DisableAllSeries()
        {
            for (int i = 0; i < this.chartHistogram.Series.Count; i++)
            {
                this.chartHistogram.Series[i].Enabled = false;
            }

            this.chkBlue.Checked = this.chkRed.Checked = this.chkGreen.Checked = this.chkGray.Checked = false;
        }

        /// <summary>
        /// Enables all series.
        /// </summary>
        private void EnableAllSeries()
        {
            for (int i = 0; i < this.chartHistogram.Series.Count; i++)
            {
                this.chartHistogram.Series[i].Enabled = true;
            }

            this.chkBlue.Checked = this.chkRed.Checked = this.chkGreen.Checked = this.chkGray.Checked = true;
        }

        /// <summary>
        /// Sets the series.
        /// </summary>
        private void SetSeries()
        {
            this.chartHistogram.Series.Clear();

            Series redSeries = new Series("Red");
            redSeries.Color = Color.Red;
            Series greenSeries = new Series("Green");
            greenSeries.Color = Color.Green;
            Series blueSeries = new Series("Blue");
            blueSeries.Color = Color.Blue;
            Series graySeries = new Series("Gray");
            graySeries.Color = Color.Gray;
            this.chartHistogram.Series.Add(redSeries);
            this.chartHistogram.Series.Add(greenSeries);
            this.chartHistogram.Series.Add(blueSeries);
            this.chartHistogram.Series.Add(graySeries);
        }
    }
}
